#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
Py40.com PyQt5 tutorial

In this example, we create a simple
window in PyQt5.

author: Jan Bodnar
website: py40.com
last edited: January 2015
"""

import sys
import os
import threading
import asyncio
from typing import Dict
from datetime import datetime
from PyQt5.QtWidgets import QApplication,QMainWindow, QWidget,QDesktopWidget,QVBoxLayout,\
    QHBoxLayout,QTreeWidget,QTreeWidgetItem,QPushButton,QTableWidget,QHeaderView,QGroupBox,\
    QTabWidget,QGridLayout,QLineEdit,QDateEdit,QTreeWidgetItemIterator,QMenu,QAction,\
    QTableWidgetItem,QAbstractItemView,QLabel,QMessageBox

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from client.control import FileFetchControl
from client.slide_button import SlideButton,DateRange

class FileFetchView(QWidget):
    def __init__(self,title:str,width:int=800,height:int=600):
        super().__init__()
        self.control = FileFetchControl(asyncio.get_event_loop())
        QDesktopWidget().getContentsMargins()
        self.resize(width,height)
        self.setWindowTitle(title)
        self.init_ui()

    def init_ui(self):
        self.center()
        #横向布局,左Tree
        hbox = QHBoxLayout()
        self.tree = QTreeWidget()
        self.tree.setColumnCount(1)
        self.tree.setHeaderLabels([' 服务器'])
        self.tree.setColumnWidth(0,120)
        self.tree.header().setStyleSheet("QHeaderView::section{background:#E5E5E5;border:1px groove gray;border-left:none;border-top:none;border-right:none;}")
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree.customContextMenuRequested.connect(self.create_tree_contextmenu)
        #self.tree.setColumnWidth(1,200)
        self.load_tree_data(self.tree)
        hbox.addWidget(self.tree)
        #hbox.addStretch(3)
        vbox = QVBoxLayout()
        top_layout = QVBoxLayout()

        line_layout = QHBoxLayout()
        line_layout.addStretch(0)

        self.btn_log = SlideButton()

        self.btn_log.setFixedSize(20, 10)
        #btn_log.setStyleSheet("QPushButton{color:red;background:blue}");
        self.btn_log.setToolTip("日志")
        self.btn_log.setAutoFillBackground(True)
        #btn_log.setFlat(True)
        self.btn_log.clicked.connect(self.change_panel)

        self.btn_task = SlideButton()
        self.btn_task.setFixedSize(20,10)
        self.btn_task.setToolTip("任务")
        self.btn_task.setAutoFillBackground(True)
        #btn_task.setFlat(True)
        self.btn_task.clicked.connect(self.change_panel)
        line_layout.addWidget(self.btn_log)
        line_layout.addWidget(self.btn_task)
        line_layout.addStretch(0)

        self.group_log = QGroupBox("日志")
        #self.group_log.setStyleSheet("QGroupBox{border-radius: 1px;background:#B0CFD7}")
        top_layout.addWidget(self.group_log, stretch=1)
        top_layout.addLayout(line_layout)
        self.init_group_log_ui(self.group_log)
        self.group_log.flag = 1
        self.btn_log.setActive(True)

        #self.group_task = QGroupBox("任务")


        #top_layout.addWidget(self.group_task,stretch=1)

        vbox.addLayout(top_layout)

        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(['服务器','执行状态','结果'])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.horizontalHeader().setStyleSheet("QHeaderView::section{background:#E5E5E5;border:1px groove gray;border-left:none;border-top:none;} QHeaderView::section:last{border-right:none;}")
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        #QTableWidget.resizeRowsToContents(self.table)
        self.table.setShowGrid(False)
        #self.table.setFrameShape(False)
        self.table.verticalHeader().setDefaultSectionSize(20)
        #需要想办法去除焦点框
        #self.table.setItemDelegate(NoFocusDelegate());
        self.table.verticalHeader().hide()
        vbox.addWidget(self.table,stretch=1)
        hbox.addLayout(vbox,stretch=1)
        self.setLayout(hbox)

        # 设置窗口透明度
        #self.setWindowOpacity(0.9)
        # 设置窗口背景透明
        #self.setAttribute(Qt.WA_TranslucentBackground)
        #self.setWindowFlag(Qt.FramelessWindowHint)  # 隐藏边框

        self.show()

    def create_tree_contextmenu(self,pos):
        if self.tree.topLevelItemCount() > 0:
            try:
                self.contextMenu = QMenu()  # 创建对象
                actionA = self.contextMenu.addAction('全选')  # 添加动作
                actionB = self.contextMenu.addAction('反选')
                #self.contextMenu.triggered[QAction].connect(self.tree_item_action_handler())
                actionA.triggered.connect(lambda : self.tree_item_action_handler(1))
                actionB.triggered.connect(lambda : self.tree_item_action_handler(2))
                self.contextMenu.exec_(self.mapToGlobal(pos))  # 随指针的位置显示菜单
                self.contextMenu.show()  # 显示
            except Exception as e:
                print(e)

    def tree_item_action_handler(self,flag):
        item_iter = QTreeWidgetItemIterator(self.tree)
        while item_iter.value():
            if flag == 1:
                item_iter.value().setCheckState(0,Qt.CheckState.Checked)
            else:
                item_iter.value().setCheckState(0,not item_iter.value().checkState(0))
            item_iter.__iadd__(1)

    def change_panel(self):
        holder = ""
        if self.group_log.flag == 1:
            self.group_log.setTitle("任务")
            holder = "任务ID"
            self.group_log.flag = 2
        else:
            self.group_log.setTitle("日志")
            holder = "日志内容"
            self.group_log.flag = 1
        self.date_log.setVisible(self.group_log.flag == 1)
        self.edit_content.setPlaceholderText(holder)
        self.btn_log.setActive(self.group_log.flag == 1)
        self.btn_task.setActive(self.group_log.flag != 1)

    def init_group_log_ui(self,group):
        grid = QGridLayout()
        self.edit_pid = QLineEdit()
        self.edit_pid.setPlaceholderText("机器人实例名")

        self.edit_content = QLineEdit()
        self.edit_content.setPlaceholderText("日志内容")

        self.date_log = DateRange(title="日志文件日期")
        # self.date_log.setCalendarPopup(True)
        # self.date_log.setDisplayFormat('yyyyMMdd')
        # self.date_log.setDate(datetime.today())

        # self.date_log = QLineEdit()
        # self.date_log.setPlaceholderText("日志文件日期")
        # self.date_log.setText(datetime.today().strftime("%Y%m%d"))

        self.btn_fetch = QPushButton("确定")
        self.btn_fetch.clicked.connect(self.do_actions)
        grid.addWidget(self.edit_pid,0,0,1,4)
        grid.addWidget(self.edit_content,1,0,1,4)
        grid.addWidget(self.date_log,2,0,1,3)
        grid.addWidget(self.btn_fetch, 2, 3, 1, 1)
        group.setLayout(grid)

    def do_actions(self):
        ips = []
        iter = QTreeWidgetItemIterator(self.tree)
        while iter.value():
            if iter.value().checkState(0) == Qt.CheckState.Checked:
                ips.append(iter.value().text(0))
            iter.__iadd__(1)

        if len(ips) == 0:
            dialog = QMessageBox(QMessageBox.Warning,"提示","请选择服务器                      ")
            dialog.exec_()
            return
        if self.edit_content.text().strip() == "":
            if self.group_log.flag == 1:
                hint = "任务ID"
            else:
                hint = "日志内容"
            dialog = QMessageBox(QMessageBox.Warning, "提示", f"请输入{hint}")
            dialog.exec_()
            return
        self.btn_fetch.setDisabled(True)
        self.table.setRowCount(len(ips))
        index = 0
        for ip in ips:
            self.table.setItem(index,0,QTableWidgetItem(ip))
            self.table.setItem(index, 1, QTableWidgetItem("执行中"))
            index+=1
        QApplication.processEvents()
        ## 1、线程池方式
        # t = threading.Thread(target=self.control.get_robot_log,args=(ips,self.edit_content.text(),
        #                                                       self.edit_pid.text(),
        #                                                       self.date_log.get_start_date(),
        #                                                       self.date_log.get_end_date(),
        #                                                       self.callback_action))
        # t.start()
        # t.join()
        #*****************************************************************************************

        if self.group_log.flag == 1:
            asyncio.run(self.control.get_robot_log_async(ips, self.edit_content.text(), self.edit_pid.text(),
                                   self.date_log.get_start_date(),
                                   self.date_log.get_end_date(),
                                   self.callback_action))
        else:
            asyncio.run(self.control.get_robot_task_async(ips, self.edit_pid.text(),self.edit_content.text(),
                                                         self.callback_action))
        self.btn_fetch.setDisabled(False)

    def callback_action(self,index: int,result:Dict[str,str] ):
        print(index,result)
        if result['success']:
            self.table.setItem(index,1,QTableWidgetItem("成功"))
            if self.table.item(index,2):
                self.table.item(index,2).setText("")
            label = self.table.cellWidget(index, 2)
            if label and isinstance(label,QLabel):
                label.setText(f"<a href='{result['message']}'>{result['message']}</a>")
            else:
                label = QLabel(f"<a href='{result['message']}'>{result['message']}</a>")
            self.table.setCellWidget(index,2,label)
            label.linkActivated.connect(self.open_explorer)

        else:
            self.table.setItem(index, 1, QTableWidgetItem("失败"))
            if self.table.cellWidget(index,2):
                self.table.removeCellWidget(index,2)
            self.table.setItem(index, 2, QTableWidgetItem(result['message']))
        QApplication.processEvents()


    def open_explorer(self,url):
        os.startfile(url)

    def load_tree_data(self,tree):
        ips = self.control.robots
        if ips:
            for ip in ips:
                item = QTreeWidgetItem(tree)
                item.setText(0, ip)
                item.setCheckState(0,Qt.CheckState.Checked)

    def center(self):
        screen = QDesktopWidget().screenGeometry()  # 获取屏幕分辨率
        # QtWidgets.QDesktopWidget().screenGeometry()中QDesktopWidget()也有括号
        # 获取窗口尺寸
        size = self.geometry()
        # 利用move函数窗口居中
        self.move(int((screen.width() - size.width()) / 2), int((screen.height() - size.height()) / 2))


if __name__ == '__main__':
    # 每一pyqt5应用程序必须创建一个应用程序对象。sys.argv参数是一个列表，从命令行输入参数。
    app = QApplication(sys.argv)
    # QWidget部件是pyqt5所有用户界面对象的基类。他为QWidget提供默认构造函数。默认构造函数没有父类。
    view = FileFetchView("远程机器人文件提取")

    # 系统exit()方法确保应用程序干净的退出
    # 的exec_()方法有下划线。因为执行是一个Python关键词。因此，exec_()代替
    sys.exit(app.exec_())